<?php


namespace app\service;


use app\index\controller\Payment;
use Redis\Redis;
use think\Db;

class DepositService
{
    /**
     * @param $biz_id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @context 添加合作店推荐任务
     */
    static function addBizTask($biz_id)
    {
        # 查询总开关
        $switch = Db::table("switch")->where(array("switch_type"=>"recommendaward","switch_status"=>1))->find();
        if(empty($switch)){
            return [];
        }
        $award = Db::table("recommend_award")->where(array("status"=>1))
            ->where("start_time<='".date("Y-m-d H:i:s")."' and end_time>'".date("Y-m-d H:i:s")."'")
            ->find();
        if(!empty($award)){
            $info = array(
                "biz_id"=>$biz_id,"create_time"=>date("Y-m-d"),"amount"=>intval($award['award_max']/$award['award_once']),
                "plan"=>0,"max_earn"=>$award['award_max'],"once_earn"=>$award['award_once'],
                "earn_balance"=>0,"earn_t"=>0,"title"=>$award['title']
            );
            $id = Db::table("recommend_biz")->insertGetId($info);
            if($id){
                $info['id'] = $id;
            }
            return $info;
        }else{
            return [];
        }
    }

    /**
     * @param $openid
     * @param $price
     * @param $biz_id
     * @return array|bool[]
     * @throws \Yansongda\Pay\Exceptions\BusinessException
     * @throws \Yansongda\Pay\Exceptions\GatewayException
     * @throws \Yansongda\Pay\Exceptions\InvalidArgumentException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     * @context 发起微信提现
     */
    static function startDeposit($openid,$price,$biz_id,$order_number='')
    {
        if(empty($order_number)){
            $order_number = getOrderNumber($biz_id);
        }
        # 进行提现
        $payment = new Payment([
            'partner_trade_no' => $order_number,              //商户订单号
            'openid' => $openid,                        //收款人的openid---oU1MG1nnH71SGTUTAY8Q7KK0POKY
            'check_name' => 'NO_CHECK',            //NO_CHECK：不校验真实姓名\FORCE_CHECK：强校验真实姓名
            //'re_user_name' => $payee_name,              //check_name为 FORCE_CHECK 校验实名的时候必须提交
            'amount' => floatval($price)*100,                       //企业付款金额，单位为分
            'desc' => 'E联车服合作店提现',                  //付款说明
        ]);
        $res = $payment->transfers();
        if ($res['status'] and $res['returnCode'] == 'SUCCESS') {
            # 提现成功,修改提现记录状态
            return array("status"=>true,"order_number"=>$order_number);
        } else {
            if($res['returnCode'] == 'SYSTEMERROR'){
                return array("status"=>false,"code"=>404);
            }else{
                return array("status"=>false,"code"=>101,"order_number"=>$order_number);
            }
        }
    }

    /**
     * @param $account_id 扣款账户id
     * @param $biz_id  门店id
     * @param $price  提现金额
     * @param $orderNUmber 订单号
     * @param $title  门店名称
     * @param int $log_id  提现记录id
     * @return bool[]
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 提现成功
     */
    static function depositSuccess($account_id,$biz_id,$price,$orderNUmber,$title,$log_id=0)
    {
        if($log_id > 0){
            Db::table("recommend_log_deposit")->where(array("id"=>$log_id))->update(array("status"=>3));
        }else{
            # 扣除今日余额
            Db::table("recommend_biz")->where(array("id"=>$account_id))->update(array("earn_balance"=>0));
            # 增加推荐提现记录
            $log_id=Db::table("recommend_log_deposit")->insertGetId(array("biz_id"=>$biz_id,"deposit_price"=>$price,"create_time"=>date("Y-m-d H:i:s"),
                "status"=>3,"order_number"=>$orderNUmber,"account_id"=>$account_id));
        }
        # 增加平台补贴
        self::addSubsidy(array("subsidy_number"=>$price,"pid"=>$log_id,"order_number"=>$orderNUmber,"biz_id"=>$biz_id));
        # 增加合作店提现记录
        self::addExpenses(array("price"=>$price,"username"=>$title));
        return array("status"=>true);
    }

    /**
     * @param $account_id
     * @param $biz_id
     * @param $price
     * @param $order_number
     * @param $openid
     * @param $title
     * @return bool[]
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     * @context 首次提现失败情况
     */
    static function depositFail($account_id,$biz_id,$price,$order_number,$openid,$title)
    {
        # 扣除今日余额
        Db::table("recommend_biz")->where(array("id"=>$account_id))->update(array("earn_balance"=>0));
        $log_array=array("biz_id"=>$biz_id,"deposit_price"=>$price,"create_time"=>date("Y-m-d H:i:s"),
            "status"=>1,"order_number"=>$order_number,"account_id"=>$account_id);
        $log_id = Db::table("recommend_log_deposit")->insertGetId($log_array);
        $log_array['id'] = $log_id;
        $redis = new Redis();
        $redis->rPush("log_deposit",$log_id);
        $redis->hSetJson("log_deposit_array",$log_id,
            array("openid"=>$openid,"logInfo"=>$log_array,"biz_title"=>$title,
                "expired"=>date("Y-m-d H:i:s",strtotime("+5 minutes")),"expired_index"=>0));
        return array("status"=>true);
    }

    /**
     * @return bool
     * @throws \Yansongda\Pay\Exceptions\BusinessException
     * @throws \Yansongda\Pay\Exceptions\GatewayException
     * @throws \Yansongda\Pay\Exceptions\InvalidArgumentException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     * @context 提现队列执行
     */
    static function depositting()
    {
        $redis = new Redis();
        $list = $redis->lRanges("log_deposit",0,-1);
        if(!empty($list)){
            foreach($list as $v){
                $info = $redis->hGetJson("log_deposit_array",$v);
                if(!empty($info)){
                    # 判断是否超过时间
                    if($info['expired']<=date("Y-m-d H:i:s")){
                        $status = self::depositAgain($info['openid'],$info['logInfo']['deposit_price'],$info['logInfo']['biz_id'],
                            $info['logInfo']['order_number'],$info);
                            continue;
                    }else{
                        continue;
                    }
                }else{
                    # 删除这个值进行下一个
                    $redis->lRem("log_deposit",$v,1);
                    continue;
                }
            }
        }else{
            self::depositInit();
        }
        return true;
    }

    /**
     * @param $openid
     * @param $price
     * @param $biz_id
     * @param $order_number
     * @param $info
     * @return bool
     * @throws \Yansongda\Pay\Exceptions\BusinessException
     * @throws \Yansongda\Pay\Exceptions\GatewayException
     * @throws \Yansongda\Pay\Exceptions\InvalidArgumentException
     * @throws \Yansongda\Pay\Exceptions\InvalidSignException
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     * @context 再次发起提现
     */
    static function depositAgain($openid,$price,$biz_id,$order_number,$info)
    {
        $redis=new Redis();
        $noRepeat = $redis->lock("recommendDepositOrder".$order_number,3);
        if(!$noRepeat){
            return false;
        }
        # 查询是否已经提现成功
        $status = Db::table("recommend_log_deposit")->field("status")->where(array("id"=>$info['logInfo']['id']))->value('status');
        if($status==3){
            $redis->lRem("log_deposit",$info['logInfo']['id'],1);
            $redis->hDel("log_deposit_array",$info['logInfo']['id']);
            return false;
        }
        $res=self::startDeposit($openid,$price,$biz_id,$order_number);
        if($res['status']){
            # 提现成功
            self::depositSuccess($info['logInfo']['account_id'],$biz_id,$price,$order_number,$info['logInfo']['biz_title'],$info['logInfo']['id']);
            $redis->lRem("log_deposit",$info['logInfo']['id'],1);
            $redis->hDel("log_deposit_array",$info['logInfo']['id']);
            return true;
        }else{
            $expiredTimeData = [10,30,60,120];
            $info['expired'] = date("Y-m-d H:i:s",strtotime("+{$expiredTimeData[$info['expired_index']]} minutes"));
            if($info['expired_index']<3){
                $info['expired_index']+=1;
            }
            $redis->hSetJson("log_deposit_array",$info['logInfo']['id'],$info);
            return false;
        }
    }

    /**
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @context 当队列中无数据时 查询是否有未成功的提现订单 每小时初始化一次
     */
    static function depositInit()
    {
        # 每1小时初始化一次
        $redis=new Redis();
        $noRepeat = $redis->lock("recommendDepositInit",3600);
        if(!$noRepeat){
            return false;
        }
        $list = Db::table("recommend_log_deposit rld")
            ->field("rld.*,b.biz_title,b.openid")
            ->leftJoin("biz b","b.id = rld.biz_id")
            ->where(array("rld.status"=>1))->select();
        if(!empty($list)){
            foreach($list as $k=>$v){
                $redis->rPush("log_deposit",$v['id']);
                $redis->hSetJson("log_deposit_array",$v['id'],
                    array("openid"=>$v['openid'],"logInfo"=>$v,"biz_title"=>$v['title'],
                        "expired"=>date("Y-m-d H:i:s",strtotime("+5 minutes")),"expired_index"=>0));
            }
            return true;
        }else{
            return false;
        }
    }

    /**
     * @param $data
     * @return bool
     * @context 增加补贴记录
     */
    static function addSubsidy($data)
    {
        $_array=array("subsidy_type"=>16,"subsidy_create"=>date("Y-m-d H:i:s"),
            "subsidy_number"=>$data['subsidy_number'],"member_id"=>0);
        if(!empty($data["pid"])){
            # 提现记录id
            $_array["pid"]=$data["pid"];
        }
        if(!empty($data["order_number"])){
            $_array["order_number"] = $data["order_number"];
        }
        if(!empty($data["biz_id"])){
            $_array["biz_id"] = $data["biz_id"];
        }
        if(!empty($data["order_type"])){
            $_array["order_type"] = $data["order_type"];
        }
        if(!empty($data["voucher_id"])){
            $_array["voucher_id"] = $data["voucher_id"];
        }
        Db::table("subsidy")->insert($_array);
        return true;
    }

    /**
     * @param $data
     * @return bool
     * @context 添加平台的费用支出
     */
    static function addExpenses($data)
    {

        $_array = array("category"=>2,"explain"=>"合作门店提现","type_id"=>22,"price"=>$data["price"],"title"=>"合作门店提现",
            "create_time"=>date("Y-m-d H:i:s"),"update_time"=>date("Y-m-d H:i:s"));
        if(!empty($data['username'])){
            $_array['username'] = $data['username'];
        }
        Db::table("expenses")->insert($_array);
        return true;
    }

}
